package com.itboye.system.helper;

import com.itboye.api.interfaces.IDomainParams;
import com.itboye.api.model.ByRequestData;
import com.itboye.api.model.ByResponseData;
import com.itboye.config.GlobalConfig;
import com.itboye.system.crypt.ByDataCrypt;
import com.itboye.system.crypt.JsonCrypt;
import com.itboye.system.exception.ByBaseException;
import com.itboye.system.exception.ByExceptionCode;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;

/**
 * ByMockApiRequestHelper.java
 * Created on  2016/7/30 09:19
 * 版本       修改时间          作者      修改内容
 * V1.0.1    2016/7/30      hebidu    初始版本
 * <p>
 * Copyright (c) 2013 杭州博也网络科技有限公司 版权所有
 * HANGZHOU BOYE TECHNOLOGY CO.,LTD. All Rights Reserved.
 */
public class ByMockApiRequestHelper {

    public void success(String msg){
        System.out.println("success= "+msg);
    }

    public ByResponseData fail(String msg){
        System.out.println("fail= "+msg);
        try {
            return  ByResponseData.fail("-1",msg, GlobalConfig.DEFAULT_CLIENT_SECRET,GlobalConfig.DEFAULT_NOTIFY_ID);
        } catch (UnsupportedEncodingException e) {
            ByConsoleHelper.info(e.getLocalizedMessage(),null);
        } catch (ByBaseException e) {
            ByConsoleHelper.info(e.getLocalizedMessage(),null);
        }

        return null;
    }


    private ByResponseData callDomain() throws ByBaseException {
        if(requestData == null){
            throw  new ByBaseException("请先设置请求参数");
        }
        String packageNS = "com.itboye.api.domain.";
        String type = requestData.getType();

        String[] splitType =  type.split("_",3);

        if(splitType.length != 3){
            throw new ByBaseException("请求接口类型参数无效!");
        }

        String domainClass = splitType[1]+"Domain";
        String methodName = splitType[2];
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring-multipledatasource.xml"});

        try {

            ByConsoleHelper.debug("调用类="+packageNS+domainClass,null);
            Class<?> cls =   Class.forName(packageNS+domainClass);
            ByConsoleHelper.debug("调用方法=" + methodName,null);
            Method method = cls.getMethod(methodName);

//          Constructor constructor = cls.getDeclaredConstructor(HashMap.class,ByRequestData.class);
            Constructor constructor = cls.getDeclaredConstructor();

            Object instance = context.getBean(domainClass); //constructor.newInstance();

            IDomainParams domainParams = (IDomainParams) instance;

            domainParams.initAllNeedParams(params,requestData);

            ByConsoleHelper.debug("对象"+instance.toString(),null);

            ByResponseData resp = (ByResponseData)method.invoke(instance);

            if(resp == null){
                ByConsoleHelper.info("返回为null",null);
            }else{
                ByConsoleHelper.info("返回信息:"+resp.toJson(),null);
                return resp;
            }


        } catch (ClassNotFoundException e) {
            ByConsoleHelper.info("找不到请求的资源类",null);
        }
        catch (NoSuchMethodException e) {
            ByConsoleHelper.info("找不到请求的资源方法",null);
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            ByConsoleHelper.info("调用目标出错" + e.getMessage(),null);
            if(e.getCause() != null){
                ByConsoleHelper.info("调用目标出错" + e.getCause().getMessage(),null);
            }
            if(e.getTargetException() instanceof ByBaseException){
                return fail(e.getTargetException().getMessage());
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return fail(e.getMessage());

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return fail(e.getMessage());
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//            return fail(e.getMessage());
        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return fail(e.getMessage());
        }

        return fail("服务器开小差了");
    }

    public ByResponseData mockAndCall(String apiType, String apiVer, HashMap params) throws UnsupportedEncodingException, NoSuchAlgorithmException, ByBaseException {
        this.params = params;
        String jsonData = JsonCrypt.toJson(getParams());
        String data = ByDataCrypt.encodeData(jsonData);

        Long timestamp = ByDateHelper.getCurrentTimeStamp();
        String notifyId = timestamp.toString();
        requestData = null;
        requestData = new ByRequestData();
        requestData.setClientId(this.clientId);
        requestData.setClientSecret(this.clientSecret);
        requestData.setAlg("md5");
        requestData.setApiVer(apiVer);
        requestData.setTimestamp(timestamp);
        requestData.setNotifyId(notifyId);
        requestData.setType(apiType);
        requestData.setAppVersion("1001");
        requestData.setAppType("ios");
        requestData.setData(data);

        HashMap<String,String> signParams = new HashMap<String, String>();
//        time + type + data + client_secret + notify_id
        signParams.put("time",requestData.getTimestamp().toString());
        signParams.put("type",requestData.getType());
        signParams.put("data",requestData.getData());
        signParams.put("alg","md5");
        signParams.put("client_secret",requestData.getClientSecret());
        signParams.put("notify_id",requestData.getNotifyId());
        //签名
        String sign = ByDataCrypt.sign(signParams);
        requestData.setSign(sign);

        return this.callDomain();
    }

    //请求参数
    private HashMap params;
    private String clientId;
    private String clientSecret;
    private ByRequestData requestData;

    public ByMockApiRequestHelper(String clientId,String clientSecret) {

        this.clientId = clientId;
        this.clientSecret = clientSecret;
        params = new HashMap();
    }

    public HashMap getParams() {
        if(this.params == null) return  new HashMap();
        return params;
    }

    public String getClientId() {
        return clientId;
    }

    public String getClientSecret() {
        return clientSecret;
    }

}
